<?php
/**
 * Created by PhpStorm.
 * User: priestll
 * Date: 20-7-14
 * Time: 下午3:05
 */

namespace App\Biz;


use App\Model\AwardsModel;
use App\Model\AwardsRecordModel;
use App\Model\StageUserModel;

use App\Model\UserModel;
use EasySwoole\Mysqli\QueryBuilder;
use EasySwoole\ORM\DbManager;
use EasySwoole\RedisPool\Redis;
use priestll\easyswoole\biz\BaseBiz;
use priestll\easyswoole\queue\Job;
use priestll\easyswoole\queue\Queue;
use Endroid\QrCode\QrCode;


class AwardsBiz extends BaseBiz
{

    const TYPE_OBJECT = 1;//实物
    const TYPE_MONEY = 2;//现金红包
    const TYPE_SCORE = 3;//积分
    const TYPE_FLOW = 4;//话费流量
    const TYPE_NONE = 5;//没有奖品
    const RANKING_KEY="awards_lucky_ranking";
    const PAGESIZE=6;
    const IS_AWARD=1;//奖品是否上架
    const IS_PRIZE=1;
    const NOT_PRIZE=0;

    //WebSocket:msg_type 消息类型 便于
    const AWARDS_MSG=100;
    const LOGS_MSG=200;



    public function getAward($user,$limit=8)
    {
        $user=UserModel::create()->where($user["id"])->get();
        $award=$user->awards($limit?:8);
        return $this->success($award);

    }
    public function cache($user_id,$round,$nickname)
    {
        $job = new Job();
        $job->setMethod('awards');
        $job->setJobData(["id"=>$user_id,"round"=>$round,"nickname"=>$nickname]);
        Queue::getInstance()->producer()->push($job);
    }
    private function get_rand($prize) {
        $prize["probability"]=(int)$prize["probability"];
        $proArr=[];
        $surplus=ceil((10000-$prize["probability"])/7);
        for ($i=$prize["id"]+1;$i<$prize["id"]+8;$i++)
        {
            $proArr[$i]=$surplus;
        }
        $proArr[$prize["id"]]=$prize["probability"];
        $result = '';

        //概率数组的总概率精度
        $proSum = array_sum($proArr);

        //概率数组循环
        foreach ($proArr as $key => $proCur) {
            $randNum = mt_rand(1, $proSum);
            if ($randNum <= $proCur) {
                $result = $key;
                break;
            } else {
                $proSum -= $proCur;
            }
        }
        unset ($proArr);
        if ((int)$result==$prize["id"])
        {
            return true;
        }
        return false;
    }
    private function get_code(  ) {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $code = "";
        for ( $i = 0; $i < 16; $i++ )
        {
            $code .= $chars[ mt_rand(0, strlen($chars) - 1) ];
        }
        return $code.time();
    }
    public function awards($user)
    {
        $res['msg_type'] = self::AWARDS_MSG;
        $res['name'] = '谢谢参与';
        $res["status"]=self::NOT_PRIZE;
        $user=UserModel::create()->field(["id","round","nickname","award_times"])->where($user["id"])->limit(1)->get();
        if (!$user->award_times)
        {
            $res["name"]="抽奖次数已用完,请分享助力增加次数";
            $this->sendSuccess($user->id, $res);
            return;
        }
        $result=[
            "round"         =>  $user->round,
            "user_id"       =>  $user->id,
            "award_id"      =>  0,
            "nickname"      =>  $user->nickname,
            "award_name"    =>  "谢谢参与，下次再接再厉",
            "status"        =>  self::NOT_PRIZE,
            'is_send' => 0
        ];
        $award=AwardsModel::create()->field(["probability","id","name","img","stock","type"])->where("stock > 0")->where(["round"=>$user->round,"is_award"=>self::IS_AWARD])->get();
        if ($award)
        {
            $awardCount=AwardsRecordModel::create()->where(["user_id"=>$user->id,"round"=>$user->round,"status"=>self::IS_PRIZE])->count();
            $awardCount++;
            $prize=$award->toArray();
            $prize["probability"]*=10000/$awardCount;
            $prize["probability"]=(int)$prize["probability"];
            $prize_res=$this->get_rand($prize);
            if ($prize_res)
            {
                $result["status"]=self::IS_PRIZE;
                $result["award_name"]=$prize["name"];
                $result["award_id"]=$prize["id"];
                $result["code"]=$this->get_code();
            }
        }

        //中奖
        $awardsRecordModel = AwardsRecordModel::create();
        $db = DbManager::getInstance();
        try {
            //开启事务
            $db->startTransaction();
            $_res=$awardsRecordModel->data($result)->save();
            if (!$_res)
            {
               throw new \Exception("保存数据失败!");
            }
            if ($result["status"]==self::IS_PRIZE)
            {
                $award->stock -- ;
                $_res=$award->update();
                if (!$_res)
                {
                    throw new \Exception("保存数据失败!");
                }
                $res["status"]=self::IS_PRIZE;
                $res['name']= "恭喜获得{$award->name}奖品，请在中奖纪录中查看";
            }
            if (!$user->award_times)
            {
                $res["name"]="抽奖次数已用完,请分享助力增加次数";
                throw new \Exception("抽奖次数已用完,请分享助力增加次数!");
            }
            $user->award_times--;
            if (!$user->update())
            {
                throw new \Exception("保存数据失败!");
            }
            //提交事务
            $db->commit();

        } catch (\Throwable  $e) {
            //回滚事务
            $db->rollback();
        } finally {
            $this->sendSuccess($user->id, $res);
            return ;
        }
    }

    public function ranking()
    {
        $redis = Redis::defer(self::DEF_REDIS);
        if (!$redis->exists(self::RANKING_KEY))
        {
            $data=[];
            $data[1]=AwardsRecordModel::create()->field(["nickname","FROM_UNIXTIME(created_at,'%m.%d %H:%i') as created_at","award_name"])->where(["status"=>self::IS_PRIZE,"round"=>1])->limit(5)->order("id","desc")->all();
            $data[2]=AwardsRecordModel::create()->field(["nickname","FROM_UNIXTIME(created_at,'%m.%d %H:%i') as created_at","award_name"])->where(["status"=>self::IS_PRIZE,"round"=>2])->limit(5)->order("id","desc")->all();
            $data[3]=AwardsRecordModel::create()->field(["nickname","FROM_UNIXTIME(created_at,'%m.%d %H:%i') as created_at","award_name"])->where(["status"=>self::IS_PRIZE,"round"=>3])->limit(5)->order("id","desc")->all();
            $data[4]=AwardsRecordModel::create()->field(["nickname","FROM_UNIXTIME(created_at,'%m.%d %H:%i') as created_at","award_name"])->where(["status"=>self::IS_PRIZE,"round"=>4])->limit(5)->order("id","desc")->all();
            $data[5]=AwardsRecordModel::create()->field(["nickname","FROM_UNIXTIME(created_at,'%m.%d %H:%i') as created_at","award_name"])->where(["status"=>self::IS_PRIZE,"round"=>5])->limit(5)->order("id","desc")->all();
            $data[6]=AwardsRecordModel::create()->field(["nickname","FROM_UNIXTIME(created_at,'%m.%d %H:%i') as created_at","award_name"])->where(["status"=>self::IS_PRIZE,"round"=>6])->limit(5)->order("id","desc")->all();
            $ranking=[
                "data" => $data,
                "msg_type"=>self::LOGS_MSG
            ];
            $ranking=json_encode($ranking);
            $redis->set(self::RANKING_KEY,$ranking,60);
        }
        else
        {
            $ranking=$redis->get(self::RANKING_KEY);
        }
        return $this->success($ranking);
    }

    public function log($user,$page)
    {
        if (!$page) $page=1;
        $where=["user_id"=>$user["id"]];
        $log=AwardsRecordModel::create()->field(["id","is_send","award_name","status","FROM_UNIXTIME(created_at,'%m.%d %H:%i') as created_at","round"])->where($where)->limit(($page-1)*self::PAGESIZE,self::PAGESIZE)->order("id","desc")->all();
        $count=AwardsRecordModel::create()->where($where)->count();
        $round=[
            1 => "第一轮",
            2 => "第二轮",
            3 => "第三轮",
            4 => "第四轮",
            5 => "第五轮",
            6 => "第六轮",
        ];
        $data=[];
        foreach ($log as $val)
        {
            $v=$val->toArray();
            $v["round"]=$round[$v["round"]];
            $data[]=$v;
        }
        return $this->success(["count"=>$count,"page"=>$page,"data"=>$data]);
    }

    public function details($id,$user_id)
    {
        $record=AwardsRecordModel::create()->field(["code","award_name"])->where(["id"=>$id,"user_id"=>$user_id,"status"=>self::IS_PRIZE,"is_send"=>0])->limit(1)->get();
        if (!$record||!$record->code)
        {
            return $this->fail("没有该中奖记录或奖品已核销");
        }
        $picture=$this->getQrcode($record->code);
        if ($picture)
        {
            return $this->success(["src"=>$picture,"name"=>$record->award_name]);
        }
        else
        {
            return $this->fail("SOMETHING TROBULE");
        }
    }

    private function getQrcode($content)
    {
        $qrCode = new QrCode();
        header('Content-Type: '.$qrCode->getContentType());
        $qrCode = new QrCode($content);
        $qrCode->setSize(300);
        $qrCode->setWriterByName('png');
        $qrCode->setMargin(10);
        $qrCode->setEncoding('UTF-8');
        $qrCode->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0, 'a' => 0]);
        $qrCode->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255, 'a' => 0]);
        $qrCode->setRoundBlockSize(true);
        $qrCode->setValidateResult(false);
        $qecodeName = "/home/www/jrky_qrcode/".time().".png";
        $qrCode->writeFile($qecodeName);
        $picture="";
        if (file_exists($qecodeName)) {
            $picture= $this->getBase64Picture($qecodeName);
        }
        return $picture;

    }
    private function getBase64Picture($img_file)
    {
        $img_base64 = '';
        if (file_exists($img_file)) {
            $app_img_file = $img_file;
            $fp = fopen($app_img_file, "r");
            if ($fp) {
                $filesize = filesize($app_img_file);
                $content = fread($fp, $filesize);
                $file_content = chunk_split(base64_encode($content));
                $img_base64 = 'data:image/png;base64,' . $file_content;
                $img_base642=str_replace('\r\n','',$img_base64);
            }
            fclose($fp);
        }
        return $img_base64;
    }


    public function verify($user_id,$code)
    {
        $record=AwardsRecordModel::create()->where(["code"=>$code,"status"=>self::IS_PRIZE,"is_send"=>0])->limit(1)->get();
        if (!$record)
        {
            return $this->fail("没有该中奖记录或奖品已核销");
        }
        $record->update([
            "is_send" => 1,
            "send_by" => $user_id,
            "send_time" => time()
        ]);
    }

}